using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;

namespace muduoDotNet.Tests
{
    public class AsyncPollerTest
    {
        private readonly ITestOutputHelper _output;

        public AsyncPollerTest(ITestOutputHelper output)
        {
            _output = output;
        }

        [Fact]
        public void TestPollerCreation()
        {
            _output.WriteLine("Testing Poller creation");
            
            var loop = new EventLoop();
            using var poller = Poller.NewDefaultPoller(loop);
            
            Assert.NotNull(poller);
            Assert.Equal(loop, poller.Loop);
            
            loop.Dispose();
            _output.WriteLine("Poller creation test completed");
        }

        [Fact]
        public void TestChannelRegistration()
        {
            _output.WriteLine("Testing Channel registration");
            
            var loop = new EventLoop();
            using var poller = Poller.NewDefaultPoller(loop);
            
            // 创建一个测试socket
            using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            var fd = socket.Handle.ToInt32();
            SocketManager.RegisterSocket(socket);
            
            var channel = new Channel(loop, fd);
            channel.EnableReading();
            
            // 在事件循环线程中更新channel
            bool updated = false;
            var resetEvent = new ManualResetEventSlim();
            
            var loopTask = Task.Run(() => loop.Start());
            
            loop.RunInLoop(() =>
            {
                try
                {
                    poller.UpdateChannel(channel);
                    Assert.True(channel.AddedToPoller);
                    updated = true;
                }
                finally
                {
                    resetEvent.Set();
                    loop.Stop();
                }
            });
            
            resetEvent.Wait(2000);
            loopTask.Wait(1000);
            
            Assert.True(updated);
            
            SocketManager.UnregisterSocket(socket);
            channel.Dispose();
            loop.Dispose();
            _output.WriteLine("Channel registration test completed");
        }

        [Fact]
        public void TestAsyncEventProcessing()
        {
            _output.WriteLine("Testing async event processing");
            
            var loop = new EventLoop();
            var resetEvent = new ManualResetEventSlim();
            bool eventProcessed = false;
            
            var loopTask = Task.Run(() => loop.Start());
            
            // 等待事件循环启动
            Thread.Sleep(100);
            
            loop.RunInLoop(() =>
            {
                try
                {
                    var poller = Poller.NewDefaultPoller(loop);
                    
                    // 测试轮询（没有实际socket，应该超时返回）
                    var activeChannels = poller.Poll(50);
                    Assert.NotNull(activeChannels);
                    
                    eventProcessed = true;
                    poller.Dispose();
                }
                finally
                {
                    resetEvent.Set();
                    loop.Stop();
                }
            });
            
            resetEvent.Wait(3000);
            loopTask.Wait(1000);
            
            Assert.True(eventProcessed);
            
            loop.Dispose();
            _output.WriteLine("Async event processing test completed");
        }

        [Theory]
        [InlineData(true)]  // 测试读事件
        [InlineData(false)] // 测试写事件
        public void TestEventTypeConversion(bool testRead)
        {
            _output.WriteLine($"Testing event type conversion - {(testRead ? "Read" : "Write")}");
            
            var loop = new EventLoop();
            using var poller = Poller.NewDefaultPoller(loop);
            
            using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            var fd = socket.Handle.ToInt32();
            SocketManager.RegisterSocket(socket);
            
            var channel = new Channel(loop, fd);
            
            if (testRead)
            {
                channel.EnableReading();
                Assert.True(channel.IsReading());
            }
            else
            {
                channel.EnableWriting();
                Assert.True(channel.IsWriting());
            }
            
            SocketManager.UnregisterSocket(socket);
            channel.Dispose();
            loop.Dispose();
            _output.WriteLine("Event type conversion test completed");
        }

        [Fact]
        public void TestChannelBuffers()
        {
            _output.WriteLine("Testing Channel buffers");
            
            var loop = new EventLoop();
            var channel = new Channel(loop, 1);
            
            var inputBuffer = channel.GetInputBuffer();
            var outputBuffer = channel.GetOutputBuffer();
            
            Assert.NotNull(inputBuffer);
            Assert.NotNull(outputBuffer);
            Assert.NotSame(inputBuffer, outputBuffer);
            
            // 测试缓冲区操作
            var testData = System.Text.Encoding.UTF8.GetBytes("Hello, World!");
            outputBuffer.Append(testData);
            
            Assert.True(outputBuffer.ReadableBytes > 0);
            Assert.Equal(testData.Length, outputBuffer.ReadableBytes);
            
            channel.Dispose();
            loop.Dispose();
            _output.WriteLine("Channel buffers test completed");
        }
    }
}